#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#include <pthread.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>


/************************* User Includes ************************/
#include "bt_wrapper.h"
#include "bt_config.h"
#include "bt_common.h"
#include "bt_phybusif_h4.h"
#include <unistd.h>
/**************************** Defines ****************************/
#define STDIN_BUF_SIZE 128

#define HW_DEBUG  printf
#define hw_strcmp strcmp

// command
#define BT_START_CMD "BT_START"


/*************************** Structs ****************************/
static bt_app_cb_t bt_app_cb =
        {

        };

/**************************** Var *********************************/
uint8_t stdin_buf[STDIN_BUF_SIZE] = {0};
uint8_t stdin_recv_len = 0;


/************************** Functions Prototype ******************/
void stdin_process_init(void);
void *stdin_process_thread(void *data);
void stdin_process_run(void);
uint8_t shell_parse(uint8_t *shell_string);

void board_init(void);


/**
 * @brief command input thread
 * @param data none
 * @return none
 */
void *stdin_process_thread(void *data)
{

    while(1)
    {
        fd_set read_fd;
        int result = 0;

        /* monitor uart rx */
        FD_ZERO (&read_fd);
        FD_SET (0, &read_fd);

        if ((result = select (1, &read_fd, NULL, NULL, NULL)) == -1)
        {
            printf("ERROR:file[%s], function[%s], line[%d] select fail\n",__FILE__,__FUNCTION__,__LINE__);
        }

        if(result > 0 && FD_ISSET ( 0, &read_fd))
        {

            memset(stdin_buf, 0 , STDIN_BUF_SIZE);
            int read_result = read(0, stdin_buf, STDIN_BUF_SIZE);
            stdin_recv_len = read_result;

            // printf("%s", stdin_buf);
        }
    }
}

/**
 * @brief create command input thread
 */
void stdin_process_init()
{
    pthread_t thread_stdin_id; /* create thread  */
    pthread_create(&thread_stdin_id, NULL, stdin_process_thread, NULL);
}

/**
 * @brief in while to run, Be aimed at parse command
 */
void stdin_process_run()
{
    if(stdin_recv_len != 0)
    {
        shell_parse(stdin_buf);
        stdin_recv_len = 0;
    }
}

uint8_t shell_parse(uint8_t *shell_string) {
    //    printf("shell_string len %lu\r\n", strlen((char *)shell_string));
    //    printf("BT_START_CMD len %lu\r\n", strlen((char *)BT_START_CMD));
    //    printf("stdin_recv_len len %hhu\r\n", stdin_recv_len);
    //    printf("status %d\r\n", hw_strcmp(BT_START_CMD, (const char *)shell_string));
    shell_string[stdin_recv_len - 1] = 0;

    if (hw_strcmp(BT_START_CMD, (const char *) shell_string) == 0) {
        HW_DEBUG("SHELL:operate bt start\r\n");
        // bt_start(&bt_app_cb);
        return 0;
    }

    return 0;
}

/**
 *  @brief Board Layer Init
 */
void board_init(void)
{
    bt_start(&bt_app_cb);
}

extern struct phybusif_cb uart_if;
int main(void){
    stdin_process_init();
    board_init();
    while(1){
        stdin_process_run();
        if(phybusif_input(&uart_if) != BT_ERR_OK)
            usleep(1000);
        sleep(1);
    }
    return 0;
}